package com.feeyo.groundservice.composewidget.view.menu_fab

import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.draggable2D
import androidx.compose.foundation.gestures.rememberDraggable2DState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.blankj.utilcode.util.ScreenUtils
import com.feeyo.groundservice.composewidget.util.dpToPx
import com.feeyo.groundservice.composewidget.util.intervalClick
import com.feeyo.groundservice.composewidget.util.pxToDp
import kotlin.math.abs
import kotlin.math.absoluteValue
import kotlin.math.roundToInt

/**
 *作者：70893 on 2025-07-04
 *描述：可以拖拽的浮动按钮
 */

enum class FloatDragPosition {
    LEFT, RIGHT
}


@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BoxScope.FloatDraggableButton(
    parentWidth: Int,
    parentHeight: Int,
    btnWidth: Float,
    btnHeight: Float,
    bgColor: Color = Color.Gray,
    position: FloatDragPosition = FloatDragPosition.RIGHT,
    shape: RoundedCornerShape = CircleShape,
    horizontalPadding: Dp = 10.dp,
    verticalPadding: Dp = 10.dp,
    onClick: () -> Unit,
    content: @Composable BoxScope.() -> Unit
) {
    val horizontal = horizontalPadding.dpToPx()
    val vertical = verticalPadding.dpToPx()

    val offset = remember {
        mutableStateOf(
            Offset(
                if (position == FloatDragPosition.RIGHT) horizontal * (-1) else horizontal,
                vertical * (-1)
            )
        )
    }

    val animateOffset = animateOffsetAsState(
        targetValue = offset.value,
        label = "FloatDraggableButton"
    )

    Box(
        modifier = Modifier
            .align(if (position == FloatDragPosition.RIGHT) Alignment.BottomEnd else Alignment.BottomStart)
            .size(btnWidth.pxToDp(), btnHeight.pxToDp())
            .offset {
                IntOffset(
                    x = animateOffset.value.x.roundToInt(),
                    y = animateOffset.value.y.roundToInt()
                )
            }
            .background(
                color = bgColor,
                shape = shape
            )
            .draggable2D(
                state = rememberDraggable2DState {
                    offset.value += it
                },
                onDragStopped = {
                    //停止的时候看看需不需要归位，是往左还是往右
                    val absX = offset.value.x.absoluteValue

                    val px = if (position == FloatDragPosition.RIGHT) {//初始在右边
                        if (absX > parentWidth / 2) {//超过一半宽度，归位到左边悬浮
                            //移动到左边时
                            (parentWidth - btnWidth) * (-1) + horizontal
                        } else {
                            //回到右边时
                            horizontal * (-1)
                        }
                    } else {//初始在左边
                        if (absX > parentWidth / 2) {//超过一半宽度，归位到右边悬浮
                            parentWidth - btnWidth - horizontal
                        } else {
                            horizontal
                        }
                    }

                    val py = offset.value.y
                        .coerceAtMost(vertical * (-1))//向下移动正值，不超过-vertical
                        .coerceAtLeast(parentHeight * (-0.7f))//向上移动负值，不超过屏幕高度的0.7倍

                    offset.value = Offset(px, py)
                }
            ).intervalClick { onClick() }
    ) {
        content()
    }
}